/*
 * Copyright (c) 2009-2012, Pieter Noordhuis <pcnoordhuis at gmail dot com>
 * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __INTSET_H
#define __INTSET_H
#include <stdint.h>

// 问题1：intset的应用场景是啥？
// 答：intset是整数集合，实现采用有序字节数组记录整数，当数据量比较小的时候，相较于红黑树能节省内存。
// 问题2：redis为什么要有encoding？
// 答：redis对外提供string, list, hash, set, zset等类型，但每个类型的内部实现可能是多样的，这时就需要内部编码

typedef struct intset {
    uint32_t encoding; // 集合里的整数类型（字节数量）: 2 | 4 | 8, 插入的整数encoding比集合的大，就需要调整encoding
    uint32_t length; // 集合里整数个数
    int8_t contents[]; // 柔性数组，整数按字节存储在这里，这些字节需要按照encoding来读取。另外这里的数据是有序的, refer：intsetSearch
} intset;

intset *intsetNew(void); // 创建空的intset
intset *intsetAdd(intset *is, int64_t value, uint8_t *success);  // 插入元素
intset *intsetRemove(intset *is, int64_t value, int *success); // 删除元素
uint8_t intsetFind(intset *is, int64_t value); // 查找元素
int64_t intsetRandom(intset *is); // 随机一个元素
int64_t intsetMax(intset *is); // 返回最大的元素
int64_t intsetMin(intset *is); // 返回最小的元素
uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value); // 获取某个位置的元素值
uint32_t intsetLen(const intset *is); // 获取intset的长度
size_t intsetBlobLen(intset *is); // 获取intset占用的字节数
int intsetValidateIntegrity(const unsigned char *is, size_t size, int deep); // 校验数据完整性

#ifdef REDIS_TEST
int intsetTest(int argc, char *argv[], int flags);
#endif

#endif // __INTSET_H
